home *** CD-ROM | disk | FTP | other *** search
- #include "extdrv.h"
- #include "file.h"
- #include "dir.h"
- #include "buffer.h"
- #include "dos.h"
- #include "extern.h"
-
- int n_rootdir;
- struct rdirbuf far *root_base = NULL, far *root_dir = NULL;
- struct rdirbuf far *root_tail = NULL;
-
- struct rdirbuf far *get_root(struct drvinfo far *d, u_int entry)
- {
- u_short off, sector;
- struct rdirbuf far *p, far *free;
-
- off = entry / N_RDIR_ENTRY;
- free = NULL;
- for (p = root_dir; p != NULL; p = p->next){
- if (p->drv == d && p->off == off){
- if (p != root_dir){
- if ((p->prev->next = p->next) == NULL)
- root_tail = p->prev;
- else
- p->next->prev = p->prev;
- p->next = root_dir;
- p->prev = NULL;
- root_dir->prev = p;
- root_dir = p;
- }
- return (p);
- }
- if (p->drv == NULL)
- free = p;
- }
- if (free == NULL){
- p = root_tail;
- if (p->pp != NULL){
- p->pp->drv = NULL; /* invalidate */
- p->pp = NULL;
- }
- if (p->dirty){
- d = p->drv;
- sector = RDIRBUFSIZ / d->sectsiz;
- sector = d->rdir_off + p->off * sector;
- if (write2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, p->buf) != 0){
- #ifdef DEBUG
- auxputs("write error ");
- #endif
- return (NULL);
- }
- p->dirty = FALSE;
- }
- root_tail = p->prev;
- p->prev->next = NULL;
- root_dir->prev = p;
- p->next = root_dir;
- p->prev = NULL;
- root_dir = p;
- } else {
- if ((p = free) != root_dir){
- if (p->next == NULL)
- root_tail = p->prev;
- else
- p->next->prev = p->prev;
- p->prev->next = p->next;
- root_dir->prev = p;
- p->next = root_dir;
- p->prev = NULL;
- root_dir = p;
- }
- }
- p->drv = d;
- p->off = off;
- if (off == d->rdir_last_sec)
- p->n_entry = d->rdir_last_size;
- else
- p->n_entry = N_RDIR_ENTRY;
-
- sector = RDIRBUFSIZ / d->sectsiz;
- sector = d->rdir_off + off * sector;
- if (read2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize, p->buf) != 0){
- #ifdef DEBUG
- auxputs("read error ");
- #endif
- p->drv = NULL;
- return (NULL);
- }
- #ifdef DEBUG_BUF
- auxputs("RBUF#");
- auxprinthex((u_long)((char far *)p - (char far *)root_base)/sizeof (struct rdirbuf));
- auxputs(" DISK-READ,");
- auxprinthex(sector);
- auxputs(",");
- auxprinthex(p->n_entry);
- auxputs(" ");
- #endif
- return (p);
- }
-
- flush_root(struct drvinfo far *d, int invalidate)
- {
- struct rdirbuf far *p;
- u_short sector;
-
- #ifdef DEBUG
- auxputs("flush_root ");
- #endif
- for (p = root_dir; p != NULL; p = p->next){
- if ((d == NULL && p->drv != NULL) || p->drv == d){
- if (p->dirty){
- d = p->drv;
- sector = RDIRBUFSIZ / d->sectsiz;
- sector = d->rdir_off + p->off * sector;
- if (write2(d, (u_long)sector, RDIRBUFSIZ/d->blocksize,
- p->buf) != 0){
- #ifdef DEBUG
- auxputs("write error ");
- #endif
- return (-1);
- }
- p->dirty = FALSE;
- }
- if (invalidate){
- if (p->pp != NULL){
- p->pp->drv = NULL; /* invalidate */
- p->pp = NULL;
- }
- p->drv = NULL;
- }
- }
- }
- return (0);
- }
-
- inv_root(u_int devno)
- {
- struct rdirbuf far *p;
-
- for (p = root_dir; p != NULL; p = p->next){
- if (p->drv != NULL && p->drv->devno == devno){
- if (p->pp != NULL){
- p->pp->drv = NULL;
- p->pp = NULL;
- }
- p->drv = NULL;
- p->dirty = FALSE;
- }
- }
- return (0);
- }
-
- struct rdirbuf far *root_read(struct drvinfo far *d, int entry)
- {
- struct rdirbuf far *p;
-
- if (entry >= d->n_rdir)
- return (NULL);
- if ((p = get_root(d, entry)) == NULL){
- return (NULL);
- }
- #ifdef DEBUG_BUF
- auxputs("RBUF#");
- auxprinthex((u_long)((char far *)p - (char far *)root_base)/sizeof (struct rdirbuf));
- auxputs(" ");
- auxputs("\r\n");
- #endif
- return (p);
- }
-